package cn.tedu.kcircle.passport.adapter.http;

import cn.hutool.core.bean.BeanUtil;
import cn.tedu.kcircle.common.exception.BusinessException;
import cn.tedu.kcircle.common.po.CurrentPrincipal;
import cn.tedu.kcircle.common.restful.ResponseCode;
import cn.tedu.kcircle.common.util.JwtUtil;
import cn.tedu.kcircle.passport.adapter.converter.PassportAdapterConverter;
import cn.tedu.kcircle.passport.protocol.param.UserLoginInfoParam;
import cn.tedu.kcircle.passport.protocol.param.UserRegisterParam;
import cn.tedu.kcircle.passport.repository.cache.UserStateCacheRepository;
import cn.tedu.kcircle.passport.repository.model.UserLoginInfoModel;
import cn.tedu.kcircle.passport.repository.model.UserRegisterModel;
import cn.tedu.kcircle.passport.repository.persist.UserRepository;
import cn.tedu.kcircle.passport.service.bo.UserLoginInfoBO;
import cn.tedu.kcircle.passport.service.bo.UserLoginResultBO;
import cn.tedu.kcircle.passport.service.bo.UserStateBO;
import cn.tedu.kcircle.passport.service.PassportService;
import com.alibaba.fastjson.JSON;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
@AllArgsConstructor
public class PassportServiceImpl implements PassportService {

    private UserRepository userRepository;
    private UserStateCacheRepository userStateCacheRepository;
    private PasswordEncoder passwordEncoder;
    private PassportAdapterConverter converter;

    @Override
    public void logOut(CurrentPrincipal principal) {
        Long id = principal.getUserId();
        userStateCacheRepository.deleteUserState(id);
    }

    @Override
    public UserLoginInfoBO getLoginInfoByUsername(String username) {
        UserLoginInfoModel userLoginInfoModel = userRepository.getLoginInfoByUsername(username);
        return converter.model2BO(userLoginInfoModel);
    }

    @Override
    public UserLoginResultBO login(UserLoginInfoParam userLoginInfoParam, HttpServletRequest request) {
        String username = userLoginInfoParam.getUsername();
        UserLoginInfoBO userLoginInfoBO = this.getLoginInfoByUsername(username);

        if (userLoginInfoBO == null) {
            throw new BusinessException(ResponseCode.ERROR_UNAUTHORIZED,"用户名或密码错误");
        }
        if(userLoginInfoBO.getEnable()==0){
            throw new BusinessException(ResponseCode.ERROR_FORBIDDEN,"账号被禁用");
        }
        if(!passwordEncoder.matches(userLoginInfoParam.getPassword(),userLoginInfoBO.getPassword())){
            throw new BusinessException(ResponseCode.ERROR_UNAUTHORIZED,"账号或密码错误");
        }

        Long userId=userLoginInfoBO.getId();
        List<String> permission = userLoginInfoBO.getPermission();
        String authoritiesJsonString= JSON.toJSONString(permission);
        UserStateBO userStateBO = new UserStateBO();
        userStateBO.setAuthorityJsonString(authoritiesJsonString);
        userStateBO.setEnable(userLoginInfoBO.getEnable());
        userStateBO.setUsername(userLoginInfoBO.getUsername());
        userStateCacheRepository.saveUserState(userId, userStateBO);
        userStateCacheRepository.renewal(userId);

        //TODO 登录日志插入数据
        //TODO 登录用户名相关信息(登录次数 最后登录ip 最后登录时间)

        CurrentPrincipal currentPrincipal = new CurrentPrincipal();
        currentPrincipal.setUserId(userId);
        //获取用户ip地址 客户端信息
        currentPrincipal.setUserAddr(request.getHeader(HEADER_USER_ADDR));
        currentPrincipal.setUserAgent(request.getHeader(HEADER_USER_AGENT));
        currentPrincipal.setUsername(userStateBO.getUsername());
        Map<String, Object> principal = BeanUtil.beanToMap(currentPrincipal);
        String jwt = JwtUtil.generate(principal, JWT_SECRET_KEY);

        UserLoginResultBO userLoginResultBO = new UserLoginResultBO();
        BeanUtils.copyProperties(userLoginInfoBO,userLoginResultBO);
        userLoginResultBO.setToken(jwt);
        return userLoginResultBO;
    }

    @Override
    public void register(UserRegisterParam userRegisterParam) {
        UserLoginInfoModel loginInfoByUsername = userRepository.getLoginInfoByUsername(userRegisterParam.getUsername());
        if(loginInfoByUsername!=null){
            throw new BusinessException(ResponseCode.ERROR_CONFLICT,"用户名被占用");
        }
        UserRegisterModel userRegisterModel = converter.param2Model(userRegisterParam);
        userRegisterModel.setPassword(passwordEncoder.encode(userRegisterModel.getPassword()));
        int insert = userRepository.insert(userRegisterModel);
        if(insert!=1){
            throw new BusinessException(ResponseCode.INTERNAL_SERVER_ERROR,"服务器内部错误");
        }
    }
}
